<template>
  <div class="verification-code-container">
    <div class="input-wrapper">
      <el-input
        v-model="code"
        :placeholder="placeholder"
        :maxlength="maxlength"
        :disabled="disabled"
        @input="handleInput"
        @focus="handleFocus"
        @blur="handleBlur"
        :validate-event="false"
      >
        <template #append>
          <el-button
            type="text"
            :disabled="countdown > 0 || disabled"
            class="send-code-btn"
            @click="handleSendCode"
          >
            {{ countdown > 0 ? `${countdown}秒后重新发送` : '发送验证码' }}
          </el-button>
        </template>
      </el-input>
    </div>
    
    <!-- 错误提示 -->
    <div v-if="error" class="error-message">{{ error }}</div>
  </div>
</template>

<script setup lang="ts">
import { ref, watch } from 'vue'
import axios from 'axios'

// 定义组件属性
const props = defineProps({
  /**
   * 绑定的值
   */
  modelValue: {
    type: String,
    default: ''
  },
  /**
   * 占位文本
   */
  placeholder: {
    type: String,
    default: '请输入验证码'
  },
  /**
   * 最大长度
   */
  maxlength: {
    type: Number,
    default: 6
  },
  /**
   * 是否禁用
   */
  disabled: {
    type: Boolean,
    default: false
  },
  /**
   * 倒计时秒数
   */
  countdownSeconds: {
    type: Number,
    default: 60
  },
  /**
   * 发送验证码的API URL
   */
  apiUrl: {
    type: String,
    default: '/api/send-code'
  },
  /**
   * 额外的API参数
   */
  apiParams: {
    type: Object,
    default: () => ({})
  }
})

// 定义组件事件
const emit = defineEmits<{
  'update:modelValue': [value: string]
  'send': []
  'sendSuccess': []
  'sendError': [error: any]
  'validate': [value: string]
}>()

// 验证码输入
const code = ref(props.modelValue)

// 倒计时
const countdown = ref(0)

// 错误信息
const error = ref('')

// 定时器
let timer: number | null = null

// 监听外部modelValue变化
watch(
  () => props.modelValue,
  (newValue) => {
    if (newValue !== code.value) {
      code.value = newValue
    }
  }
)

// 处理输入
const handleInput = (value: string) => {
  // 只允许输入数字
  if (!/^\d*$/.test(value)) {
    code.value = code.value.replace(/\D/g, '')
    return
  }
  emit('update:modelValue', value)
  emit('validate', value)
}

// 处理发送验证码
const handleSendCode = async () => {
  if (countdown.value > 0 || props.disabled) {
    return
  }
  
  // 清空错误信息
  error.value = ''
  
  try {
    emit('send')
    
    // 发送请求
    const response = await axios.post(props.apiUrl, {
      ...props.apiParams
    })
    
    // 开始倒计时
    startCountdown()
    
    emit('sendSuccess')
    
    // 显示成功提示
    console.log('验证码发送成功:', response.data)
  } catch (err: any) {
    error.value = err.response?.data?.message || '验证码发送失败，请重试'
    emit('sendError', err)
    
    console.error('验证码发送失败:', err)
  }
}

// 开始倒计时
const startCountdown = () => {
  countdown.value = props.countdownSeconds
  
  // 清除之前的定时器
  if (timer) {
    window.clearInterval(timer)
  }
  
  timer = window.setInterval(() => {
    if (countdown.value > 0) {
      countdown.value--
    } else {
      if (timer) {
        window.clearInterval(timer)
        timer = null
      }
    }
  }, 1000)
}

// 处理聚焦
const handleFocus = () => {
  // 可以在这里添加聚焦时的处理逻辑
}

// 处理失焦
const handleBlur = () => {
  // 可以在这里添加失焦时的处理逻辑
}

// 组件卸载时清除定时器
import { onUnmounted } from 'vue'

onUnmounted(() => {
  if (timer) {
    window.clearInterval(timer)
  }
})
</script>

<style scoped>
.verification-code-container {
  width: 100%;
  position: relative;
}

.input-wrapper {
  position: relative;
}

.send-code-btn {
  color: #1890ff;
  font-size: 14px;
  padding: 0 10px;
  white-space: nowrap;
}

.send-code-btn:disabled {
  color: #999;
  cursor: not-allowed;
}

.error-message {
  color: #f56c6c;
  font-size: 12px;
  line-height: 1;
  padding-top: 4px;
  min-height: 18px;
}

/* 适配不同的输入框尺寸 */
:deep(.el-input__wrapper) {
  border-radius: 4px;
}

:deep(.el-input__inner) {
  padding-right: 120px !important;
}

/* 响应式调整 */
@media (max-width: 480px) {
  .send-code-btn {
    font-size: 12px;
    padding: 0 6px;
  }
  
  :deep(.el-input__inner) {
    padding-right: 100px !important;
  }
}
</style>